#ifndef NETWORK_UDPIO_H_
#define NETWORK_UDPIO_H_

#include <iostream>
#include <string>

#ifdef _WIN32
	#include <windows.h>
	#include <sys/types.h>
	#include <winsock.h>
	#include <unistd.h> // usleep function
#else
	#include <sys/types.h>
	#include <sys/socket.h>
	#include <netinet/in.h>
	#include <netdb.h>
#endif

#include "Packet.h"

#ifdef _WIN32
	typedef int socklen_t;
#endif

namespace Network {

/*
 * Klasa stanowi warstwe abstrakcji pomiedzy programem a protokolem UDP. Pojedynczy obiekt
 * UDPIO wiaze sie z pojedynczym gniazdem UDP i pozwala na zapis do niego, a takze
 * generuje zdarzenia, kiedy odebrana zostanie wiadomosc. Wiadomosc moze skladac sie z kilku
 * pakietow UDP - w takim wypadku UDPIO wewnetrznie buforuje nadchodzace pakiety i generuje
 * zdarzenie odebrania wiadomosci dopiero, kiedy zostanie ona odebrana w calosci.
 */
class UDPIO {
public:
	enum MsgType {
	/* from client: */
		//
		DISCOVERY, JOIN,
		PING,
		// commands:
		SET_BEHAVIOUR, SET_FACING, SET_B_AND_F,
	/* from server: */
		DISCOVERY_REPLY, JOIN_ACC, JOIN_NAC,
		STATE_UPLOAD_COMPLETE,
		OBJECT_UPDATE, EVENT, PLAYER_EVENT, PING_REPLY
	};

protected:
	static const int BUF_SIZE = 255;
	static const int PORT = 24001;
	static const float DELTA_TIME = 0.25f;

	int sock_;
	struct sockaddr_in target_;
	float timeoutAccumulator_;

	UDPIO();
	~UDPIO();

	void wait(float seconds);

	Packet receivePacket();
	int sendPacket(Packet packet);
}; //class UDPIO

} //namespace Network

#endif /* NETWORK_UDPIO_H_ */
